#include "EquationSolver.hpp"
#include <iostream>

using namespace std; 

class F1 : public Function{
public:
    double operator() (double x) const{
        return sin(x/2)-1;
    }
    double derivative(double x) const{
        return 0.5*cos(x/2);
    }
}f1;

class F2 : public Function{
public:
    double operator() (double x) const{
        return pow(M_E,x)-tan(x);
    }
    double derivative(double x) const{
        return pow(M_E,x)-1/(pow(cos(x),2));
    }
}f2;

class F3 : public Function{
public:
    double operator() (double x) const{
        return pow(x,3)-12*x*x+3*x+1;
    }
    double derivative(double x) const{
        return 3*x*x-24*x+3;
    }
}f3;


void solve_F11() {
    cout << "Solving sin(x/2)-1 with x0=0,x1=pi/2" << endl;
    Secant_Method solver_f1(F1(),0,M_PI/2);
    double x = solver_f1.solve();
    cout << "A root is :" << x << endl;
    cout << "Error is :" << f1(x) << endl;
}

void solve_F12() {
    cout << "Solving sin(x/2)-1 with x0=0,x1=pi/3" << endl;
    Secant_Method solver_f1(F1(),0,M_PI/3);
    double x = solver_f1.solve();
    cout << "A root is :" << x << endl;
    cout << "Error is :" << f1(x) << endl;
}

void solve_F21() {
    cout << "Solving e^x-tan(x) with x0=1,x1=1.4" << endl;
    Secant_Method solver_f2(F2(),1,1.4);
    double x = solver_f2.solve();
    cout << "A root is :" << x << endl;
    cout << "Error is :" << f2(x) << endl;
}

void solve_F22() {
    cout << "Solving e^x-tan(x) with x0=0.5,x1=1" << endl;
    Secant_Method solver_f2(F2(),0.5,1);
    double x = solver_f2.solve();
    cout << "A root is :" << x << endl;
    cout << "Error is :" << f2(x) << endl;
}

void solve_F31() {
    cout << "Solving x^3-12*x*x+3*x+1 with x0=0,x1=-0.5" << endl;
    Secant_Method solver_f3(F3(),0,-0.5);
    double x = solver_f3.solve();
    cout << "A root is :" << x << endl;
    cout << "Error is :" << f3(x) << endl;
}

void solve_F32() {
    cout << "Solving x^3-12*x*x+3*x+1 with x0=0.5,x1=0" << endl;
    Secant_Method solver_f3(F3(),0.5,0);
    double x = solver_f3.solve();
    cout << "A root is :" << x << endl;
    cout << "Error is :" << f3(x) << endl;
}

int main() {
    solve_F11();
    solve_F12();
    solve_F21();
    solve_F22();
    solve_F31();
    solve_F32();
    return 0;
}
